//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __CAUDIOCARD_H__
#define __CAUDIOCARD_H__

#include <ddk.h>
#include "nu_api.h"
#include <elaaudio.h>

enum
{
	FIH_VOICE_MIC_AND_VOICE_RECEIVER                 = 0,
	FIH_VOICE_MIC_AND_VOICE_LOUDSPEAKER              = 1,
	FIH_VOICE_HEADPHONE_MIC_AND_VOICE_HEADPHONE      = 2,
	FIH_VOICE_HEADPHONE_MIC_AND_VOICE_HEADPHONE_MONO = 3,
	FIH_VOICE_BT                                     = 4,
	FIH_VOICE_RECEIVER                               = 5,
	FIH_VOICE_MIC                                    = 6,
	FIH_VOICE_HEADPHONE_MIC                          = 7,
	FIH_STEREO_LOUDSPEAKER                           = 8,
	FIH_STEREO_HEADPHONE                             = 9,
	FIH_STEREO_HEADPHONE_MONO                        = 10,
	FIH_STEREO_BT                                    = 11,
	FIH_FM_AND_HEADPHONE                             = 12,
	FIH_FM_AND_HEADPHONE_MONO                        = 13,
	FIH_FM_AND_LOUDSPEAKER                           = 14,
	FIH_ALL_PATH_CLOSE                               = 15,
	FIH_IIS_HEADPHONE_RINGTONE                       = 16,
	/*FIH Leon Wu, 20090408, PPE_CR:252 : add audio path from MA117 IIS and BT A2DP*/
	FIH_IIS_LOUDSPEAKER   				= 17,
	FIH_IIS_HEADPHONE   				= 18,
	FIH_STEREO_BT_A2DP   				= 19,
	/*FIH Leon Wu, 20090408, PPE_CR:252*/
	FIH_MAX_PATH_INFO                                = 20
};


typedef enum
{
    FIH_AUD_NO_ERROR,
    FIH_AUD_ALREADY_REGISTERED,
    FIH_AUD_APP_NOT_REGISTERED,
    FIH_AUD_INVALID_ARGUEMENT,
    FIH_AUD_INVALID_ATTRIBUTE,
    FIH_AUD_SERVICE_NOT_INITIALIZED,
    FIH_AUD_SERVICE_ALREADY_INITIALIZED,
    FIH_AUD_MAX_APPLICATIONS_REGISTERED,
    FIH_AUD_ATTRIBUTES_ALREADY_SET,
    FIH_AUD_BUSY,
    FIH_AUD_VALUE_ERROR,
    FIH_AUD_FILE_NOT_EXIST,
    FIH_AUD_FILE_ALREADY_EXIST,
    FIH_AUD_ERROR
}FIH_AUD_GEN_ERR;

typedef enum
{
    AUDIO_RESULT_SUCCESS              =  1,
    AUDIO_RESULT_FAIL                 = -1,
    AUDIO_RESULT_FAIL_TIMEOUT         = -2,
    AUDIO_RESULT_PATH_ID_MISMATCH     = -3,
    AUDIO_RESULT_FAIL_BAD_PARAM       = -4
} Audio_Result;

typedef enum
{
    AUDIO_HEADSET_PLUGGED				= 1,
    AUDIO_HEADSET_UNPLUGGED			= 2,
    AUDIO_HEADSET_HOOK_DETECT_ON		= 3,
    AUDIO_HEADSET_HOOK_DETECT_OFF	= 4
}BspTwl3029_AudioAccessoryEvent;

typedef enum
{
    AUDIO_APPS_EVENT_SYNC_UPDATE_IND = 0,
    AUDIO_APPS_EVENT_OVERFLOW_IND,
    AUDIO_APPS_EVENT_UNDERFLOW_IND,
    AUDIO_APPS_EVENT_SESSION_STOPPED,
    AUDIO_APPS_EVENT_START_ERROR,
    AUDIO_APPS_EVENT_STOP_ERROR,
    AUDIO_APPS_EVENT_UPDATE_ERROR,
    AUDIO_APPS_EVENT_WAITING_INPUT,
    AUDIO_APPS_EVENT_WAITING_OUTPUT,
    AUDIO_APPS_EVENT_NO_EVENT
}Audio_eventType;

typedef enum
{
    AUDIO_SESSION_PLAY            = 1,
    AUDIO_SESSION_RECORD          = 2,
    AUDIO_FORMAT_PCM              = 4,
}AUDIO_sessionType;

typedef struct AudioPCMBuffer{
    /*
    SessionType is combination of   Direction | Channel rate | DTX.
    */
    unsigned short sessionType;
    /* memory allocated for input circular buffer is assigned to this */
    signed short *bufferStart;
    /* size of input circular buffer */
    unsigned long  bufferSize;
    /* Current applications status on Input circula buffer */
    unsigned long writeOffset;
    /* will be set to TRUE if SESSION_STOPPED is received from ASFM. */
    unsigned long asfmReadOffset;
    /*
    * will be set to TRUE if ASFM API startSession is called and will be set to
    * FALSE when ASFM API stopSession is called.
    */
    unsigned char isStarted;
    /* The session number is returned from ASFM start session function call. */
    unsigned char sessionNumber;
    /*If the value is 5 then event will be generated after processing 5 * 20ms
    of data */
    unsigned long wakeupEventPeriod;
    /* Uplink level*/
    unsigned short uplinkLevel;
    /* Downlink level*/
    unsigned short downlinkLevel;
    /* Uplink speed*/
    unsigned short uplinkSpeed;
    /* Downlink speed*/
    unsigned short downlinkSpeed;
    unsigned char isStopped;
}AudioPCMBuffer;

typedef struct
{
  signed short *bufferStart;
  UInt32 bufferSize;
  UInt32 AppStatus;
  UInt32 DSPStatus;
  Int8   sessionNumber;
  UInt8  unitByte;
  UInt32 wakeupEventPeriod;
} RecordPCMBuffer;

typedef enum
{
  BUFFER_ERROR = -1,
  BUFFER_SUCCESS,
  BUFFER_FULL,
  BUFFER_EMPTY,
  BUFFER_SUSPEND
} BUFFER_RETURN_CODE;

typedef struct {
    Audio_Params params;
    int buf_size;
}AudioParamsWithBufSize;

// Audio out device
#define AODEVICE_SPEAKER    0
#define AODEVICE_HEADSET    1
#define AODEVICE_BTHEADSET  2
#define AODEVICE_HEADPHONE_RINGTONE 3

#define MAX_VOLUME 255
#define FIH_MAX_VOLUME 10
#define CIRCULAR_BUFFER_SIZE 8192

class CAudioCard : public CDeviceDriver {
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 offset,
        /* [in] */ const MemoryBuf &buffer,
        /* [out] */ Int32* pBytesWritten,
        /* [out] */ IEvent** completionEvent);

    CARAPI Control(
        /* [in] */ Handle32 controlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf* pOutBuffer,
        /* [out] */ IEvent** completionEvent);

    virtual void Dispose();

    CAudioCard()
    {
        m_volume = 5;
        m_AppPath = FIH_ALL_PATH_CLOSE;
        m_CurrentPath = FIH_ALL_PATH_CLOSE;
        m_SampleRate = 0;
        m_BitRate = 0;
        m_Channels = 0;
        m_BufferSize = 0;
    }

    ECode AudioCallbackThread(void *arg);
    ECode Audio_Write(short *wav_buffer, unsigned long size, unsigned long *copy_size);
    ECode Audio_Read(UInt8* pBuffer, Int32 uBytesToRead, Int32 *pReadSize);

    DzMutex   m_lock;
    long m_AppPath;
    long m_CurrentPath;
    int m_volume;
    DzEvent m_AudioCallbackEvent;
    DzEvent m_AudioHeadsetCallbackEvent;
    DzEvent m_AudioStopEvent;

    int m_SampleRate;
    short m_BitRate;
    short m_Channels;
    int m_BufferSize;
};

#endif // __CAUDIOCARD_H__
